package cn.iocoder.yudao.module.trade.cart.convert;

import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.module.api.product.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.api.product.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.api.product.spu.enums.ProductSpuStatusEnum;
import cn.iocoder.yudao.module.api.shop.info.dto.ShopInfoDTO;
import cn.iocoder.yudao.module.api.shop.info.enums.ShopStatusEnum;
import cn.iocoder.yudao.module.trade.cart.dal.dataobject.CartDO;
import cn.iocoder.yudao.module.trade.cart.vo.AppCartItemRespVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;

@Mapper
public interface TradeCartConvert {

    TradeCartConvert INSTANCE = Mappers.getMapper(TradeCartConvert.class);

    default List<AppCartItemRespVO> convertList(List<CartDO> carts, Map<Long, ShopInfoDTO> shops,
                                                List<ProductSpuRespDTO> spus, List<ProductSkuRespDTO> skus,
                                                int deductUnitPrice, int discountPercent) {
        Map<Long, ProductSpuRespDTO> spuMap = convertMap(spus, ProductSpuRespDTO::getId);
        Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId);
        // 遍历，开始转换
        List<AppCartItemRespVO> list = new ArrayList<>(carts.size());
        carts.forEach(cart -> {
            AppCartItemRespVO cartItemRespVO = new AppCartItemRespVO();
            cartItemRespVO.setId(cart.getId());
            cartItemRespVO.setShopId(cart.getShopId());
            cartItemRespVO.setCount(cart.getCount());
            cartItemRespVO.setSelected(cart.getSelected());
            cartItemRespVO.setInvalid(false);
            cartItemRespVO.setInvalidReason("");
            ShopInfoDTO shop = shops.get(cart.getShopId());
            ProductSpuRespDTO spu = spuMap.get(cart.getSpuId());
            cartItemRespVO.setSpu(spu);
            ProductSkuRespDTO sku = skuMap.get(cart.getSkuId());
            if (sku != null) {
                sku.setPointDeductUnitPrice(deductUnitPrice);
                sku.setMemberLevelPrice(calculateMemberLevelPrice(discountPercent, sku.getPrice()));
                cartItemRespVO.setSku(sku);
            } else {
                cartItemRespVO.setSku(null);
            }
            // 若产品已失效，则强制设置成不可选中。虽然 SKU 可能也会不存在，但是可以通过购物车重新选择
            if (shop == null) {
                cartItemRespVO.setInvalid(true);
                cartItemRespVO.setInvalidReason("店铺不存在");
                cartItemRespVO.setSelected(false);
            } else if (CommonStatusEnum.isDisable(shop.getEnabled())) {
                cartItemRespVO.setInvalid(true);
                cartItemRespVO.setInvalidReason("店铺已被封禁");
                cartItemRespVO.setSelected(false);
            } else if (!Objects.equals(shop.getStatus(), ShopStatusEnum.OPENING.getValue())) {
                cartItemRespVO.setInvalid(true);
                cartItemRespVO.setInvalidReason("店铺未营业");
                cartItemRespVO.setSelected(false);
            } else if (spu == null) {
                cartItemRespVO.setInvalid(true);
                cartItemRespVO.setInvalidReason("产品不存在");
                cartItemRespVO.setSelected(false);
            } else if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) {
                cartItemRespVO.setInvalid(true);
                cartItemRespVO.setInvalidReason("产品已下架");
                cartItemRespVO.setSelected(false);
            } else if (spu.getStock() <= 0) {
                cartItemRespVO.setInvalid(true);
                cartItemRespVO.setInvalidReason("产品库存不足");
                cartItemRespVO.setSelected(false);
            } else if (sku == null) {
                cartItemRespVO.setInvalid(true);
                cartItemRespVO.setInvalidReason("产品 SKU信息不存在");
                cartItemRespVO.setSelected(false);
            }
            list.add(cartItemRespVO);
        });
        return list;
    }

    private Integer calculateMemberLevelPrice(Integer discountPercent, Integer price) {
        if (discountPercent == null || discountPercent <= 0) {
            return price;
        }
        Integer newPrice = price * discountPercent / 100;
        return price - newPrice;
    }

}
